import Icon from '@/components/Icon'
import { useInitialState } from '@/hooks/use-initial-state'
import { getUserProfile } from '@/store/actions/profile'
import { getToken } from '@/utils/token'
import { NavBar, Input } from 'antd-mobile'
import { useEffect, useRef, useState } from 'react'
import { useHistory } from 'react-router-dom'
import { io, Socket } from 'socket.io-client'
import styles from './index.module.scss'

type Message = {
  type: 'robot' | 'user'
  text: string
}

const Chat = () => {
  const history = useHistory()

  const chatListRef = useRef<HTMLDivElement>(null)

  const [messages, setMessages] = useState<Message[]>([
    { type: 'robot', text: '亲爱的用户您好，小智同学为您服务。' },
    { type: 'user', text: '你好' }
  ])

  // 消息输入框的值
  const [message, setMessage] = useState('')

  const onSendMessage = (e: React.KeyboardEvent<HTMLInputElement>) => {
    // console.log(e)
    if (e.key === 'Enter') {
      // 通过socket.io客户端向服务端发送消息
      socketRef.current?.emit('message', {
        msg: message,
        timestamp: Date.now()
      })

      // 将当前发送的消息添加到聊天记录列表中
      setMessages((messages) => [...messages, { type: 'user', text: message }])

      // 发送后，要清空输入框
      setMessage('')
    }
  }

  const { userProfile } = useInitialState(getUserProfile).profile

  // 存储socket.io连接的引用
  const socketRef = useRef<Socket | null>(null)

  useEffect(() => {
    // 1.创建客户端实例
    const socket = io('http://toutiao.itheima.net', {
      transports: ['websocket'],
      query: {
        token: getToken().token
      }
    })

    // 2.监听连接成功事件
    socket.on('connect', () => {
      // 向聊天记录中添加一条消息
      setMessages((messages) => [
        ...messages,
        { type: 'robot', text: '我现在恭候着您的提问。' }
      ])
    })

    // 3.监听收到消息事件
    socket.on('message', (data) => {
      // 将机器人回复的消息添加到聊天列表中：
      // console.log('有消息')
      setMessages((messages) => {
        return [...messages, { type: 'robot', text: data.msg }]
      })
    })

    // 4.将客户端实例缓存到ref引用中， 避免当前页面下次渲染再次创建
    socketRef.current = socket

    // 5.在组件销毁时关闭连接
    return () => {
      socket.close()
    }
  }, [])

  // 通过 useEffect 监听聊天列表数据的变化，在渲染完成后设置聊天容器元素的 scrollTop(服务端发送的消息无法自动重置scrollTop？)

  useEffect(() => {
    const div = chatListRef.current!
    div.scrollTop = div.scrollHeight
  }, [messages])

  return (
    <div className={styles.root}>
      {/* 顶部导航栏 */}
      <NavBar className="fixed-header" onBack={() => history.go(-1)}>
        小智同学
      </NavBar>

      {/* 聊天记录列表 */}
      <div className="chat-list" ref={chatListRef}>
        {messages.map((msg, index) => {
          return msg.type === 'robot' ? (
            <div className="chat-item" key={index}>
              <Icon name="iconbtn_xiaozhitongxue" />
              <div className="message">{msg.text}</div>
            </div>
          ) : (
            <div className="chat-item user" key={index}>
              <img src={userProfile.photo} alt="" />
              <div className="message">{msg.text}</div>
            </div>
          )
        })}
      </div>

      {/* 底部消息输入框 */}
      <div className="input-footer">
        <Input
          className="no-border"
          placeholder="请描述您的问题"
          value={message}
          onChange={(val) => {
            setMessage(val)
          }}
          onKeyUp={(e) => {
            onSendMessage(e)
          }}
        />
        <Icon name="iconbianji" />
      </div>
    </div>
  )
}

export default Chat
